from django.conf import settings
from django.shortcuts import render
from django_redis import get_redis_connection
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from rest_framework.response import Response

from dingxiang.utils.ronglianyunapi import send_message
from users.backends import get_user, CustomJwtModelBackend
from users.models import UserModel
from users.serial import RegisterSerializer, SmsLoginSerializer, UserInfoSerializer
from rest_framework.generics import CreateAPIView
from rest_framework import status, viewsets


# Create your views here.


# 用户创建视图，主要用于测试
class CreateUserView(APIView):
    def get(self, request):
        # create_user 作用是给密码以密文存储
        UserModel.objects.create_user(username='test', password='123456', email='admin@163.com', mobile='12345678901')
        return Response({"msg": "用户创建成功"})


# 注册视图
class RegisterView(CreateAPIView):
    queryset = UserModel.objects.all()
    serializer_class = RegisterSerializer


# 手机号唯一验证，用于在登录时判断手机号是否被注册
class MobileAPIView(APIView):
    def get(self, request, mobile):

        user = UserModel.objects.filter(mobile=mobile).first()
        print(user)
        if user:
            return Response({"message": "手机号已存在"}, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response({"message": "未被注册,手机号可用"}, status=status.HTTP_200_OK)


# 短信验证
class SmsAPIView(APIView):
    def get(self, request, mobile):
        # ----------------redis：短信验证码缓存--------------------
        # 获取redis数据库连接
        redis = get_redis_connection('sms')
        # 调用ttl命令时，它会返回这个key在Redis中的剩余生存时间（以秒为单位）。如果key不存在，返回-2；如果key存在但没有设置过期时间，返回-1。
        # 查询Redis数据库中与特定手机号码关联的key（如'sms_1234567890'）的剩余生存时间
        res_interval = redis.ttl(f'sms_{mobile}')
        if res_interval != -2:
            return Response({"message": "验证码还在有效期内，请勿频繁发送验证码"}, status=status.HTTP_400_BAD_REQUEST)
        # ----------------redis：短信验证码缓存--------------------

        # 获取容联云的配置信息
        rly = settings.RONG_LIAN_YUN
        # 获取短信模版
        tid = rly.get('reg_tid')
        # 获取发送间隔
        sms_interval = rly.get('sms_interval_time')
        # 获取验证码
        sms_expire = rly.get('sms_expire_time')

        # 生成随机数
        from random import randint
        # 生成四位随机数,格式化操作，不足四位前面补0
        code = f'{randint(0, 9999):04d}'
        # 发送间隔时间转换,因为容联云是以分钟为单位，而配置表里是s，所以需要转换为分钟
        interval = sms_interval / 60

        # 生成发送短信的datas
        datas = (code, interval)
        # 发送短信
        # tid = '1' # 短信模板ID
        # mobile = '1861880000000' # 手机号码
        # datas = ('1234', '5') # 验证码和有效时间
        # 将参数发送给ronglianyunapi.py中进行发送

        # -------------异步celery发送短信验证码-------------
        # 调用send_sms函数，传入三个参数，分别是短信模板id，手机号，验证码
        # 为了调试，不用发短信验证码给自己，所以直接返回True

        # res = send_sms(tid, mobile, datas)
        from mycelery.sms.tasks import send_sms
        # 异步发送短信验证码,delay()是异步执行的标志，它会立即返回，但不会阻塞主线程的执行
        send_sms.delay(tid, mobile, datas)
        # -------------异步celery发送短信验证码-------------

        # --------------redis：短信验证码缓存--------------------
        # 缓存事务
        # 创建一个管道，可以一次性执行多个命令
        pipe = redis.pipeline()
        # 开启管道
        # 它通常与 pipe.exec() 一起使用，以执行在 multi() 和 exec() 之间排队的所有命令。
        pipe.multi()
        # 设置短信验证码,有效期为sms_expir和验证码code
        # setex(key, time, value)设置带有过期时间的key，单位为秒
        redis.setex(f'sms_{mobile}', sms_expire, code)
        # 设置短信发送间隔,有效期为sms_interval和'-'
        redis.setex(f'sms_interval_{mobile}', sms_interval, '-')
        # 执行管道
        pipe.execute()
        # --------------redis：短信验证码缓存--------------------
        # if res:

        return Response({"message": "短信发送成功"}, status=status.HTTP_200_OK)

        # else:
        #     return Response({"message": "短信发送失败"}, status=status.HTTP_400_BAD_REQUEST)



# 短信登录
class SmsLoginView(CreateAPIView):
    queryset = UserModel.objects.all()
    serializer_class = SmsLoginSerializer

# celery -A mycelery.man worker -l INFO -P eventlet -c 10

# 首页显示头像
class UserInfoView(viewsets.ModelViewSet):
    permission_classes = [IsAuthenticated]
    queryset = UserModel.objects.all()
    serializer_class = UserInfoSerializer
